import { ElNotification } from "element-plus";
import NProgress from "nprogress";
import "nprogress/nprogress.css";
import { createRouter, createWebHashHistory } from "vue-router";
import frameRoutes from "./frameRoutes";
import layoutRoutes from "./layoutRoutes";
import pinia from "@/stores";
import { useMenuTagsStore } from "@/stores/menuTags";

const menuTagsStore = useMenuTagsStore(pinia); // 非vue实例内部，需要传入pinia实例才能获取到对应的store
const routes = frameRoutes;

// layout路由扁平化
const layoutRoutesFlat = flatAsyncRoutes(layoutRoutes);

// 添加layout路由
addLayoutRoutes(layoutRoutesFlat);

// 创建路由对象
const router = createRouter({
  //history: createWebHistory(import.meta.env.BASE_URL),
  history: createWebHashHistory(),
  routes: initRoutesComponentName(routes),
});

router.beforeEach(async (to, from, next) => {
  // 不在打开的标签内才触发 打开加载进度动画 切换标签不需要
  if (menuTagsStore.allTagName.indexOf(to.name) === -1) {
    NProgress.start();
  }

  // 菜单标签 store
  if (to.meta.routeType !== "base") {
    menuTagsStore.addTag(to); // 添加打开标签
  }

  next();
});
router.afterEach((to, from) => {
  NProgress.done();
});

router.onError((error) => {
  NProgress.done();
  ElNotification.error({
    title: "路由错误",
    message: error.message,
  });
});

// 给router对象添加自定义方法 获取菜单
//入侵追加自定义方法、对象
router.jxf_getMenu = () => {
  const layoutMenu = [...layoutRoutes];
  return layoutMenu;
};

/**
 * 添加layout路由
 */
function addLayoutRoutes(_layoutRoutes) {
  let index = routes.findIndex((item) => {
    return item.name === "layout";
  });
  _layoutRoutes.forEach((route) => {
    routes[index].children.push(route);
  });
}

// 初始化路由参数的组件名称（目的是给组件name赋值，以便使用keep-alivea组件缓存）
function initRoutesComponentName(routes) {
  let r_routes = [];
  routes.forEach(async (route) => {
    let temRoute = { ...route };
    if (temRoute.children) {
      // 递归
      temRoute.children = initRoutesComponentName(temRoute.children);
    }
    // 如果不需要初始化，需要给route对象设置notSetComponentName = true ,默认都需要设置
    if (!temRoute.notSetComponentName) {
      if (typeof temRoute.component === "function") {
        // 如果是懒加载组件，则包一层，在内部给组件name赋值
        let componentFn = temRoute.component;
        temRoute.component = async () => {
          let _component = await componentFn();
          _component.default.name = temRoute.name;
          return _component;
        };
      }
    }

    r_routes.push(temRoute);
  });
  return r_routes;
}

//路由扁平化
function flatAsyncRoutes(routes, breadcrumb = []) {
  let res = [];
  routes.forEach((route) => {
    const tmp = { ...route };
    !tmp.meta ? (tmp.meta = { breadcrumb: [] }) : (tmp.meta.breadcrumb = []); //如果tmp.meta.breadcrumb不存在，则创建
    let tmpBreadcrumb = [...breadcrumb];
    tmpBreadcrumb.push(tmp);
    tmp.meta.breadcrumb = tmpBreadcrumb;
    res.push(tmp);
    if (tmp.children) {
      let childrenRoutes = flatAsyncRoutes(tmp.children, tmpBreadcrumb);
      delete tmp.children;
      childrenRoutes.map((item) => {
        res.push(item);
      });
    }
  });
  return res;
}

export default router;
